package org.zachary.creditbusiness.commodityandhouse.scheduler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.zachary.creditbusiness.commodityandhouse.entity.HouseOrder;
import org.zachary.creditbusiness.commodityandhouse.mapper.HouseOrderMapper;
import org.zachary.creditbusiness.commodityandhouse.util.SendHouseOrder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 房屋订单守约状态定时任务
 * 每天凌晨执行，更新房屋订单的守约状态
 */
@Component
public class HouseOrderComplianceScheduler {

    @Autowired
    private HouseOrderMapper houseOrderMapper;

    @Autowired
    private SendHouseOrder sendHouseOrder;

    /**
     * 持续扫描房屋订单守约状态，每天执行一次
     * 规则：
     * 1. 未支付且当前时间小于截止时间：显示剩余天数（promise = 0）
     * 2. 未支付且当前时间大于截止时间：显示逾期天数（promise = 1）
     * 3. 截止日期前支付：显示守约（promise = 0）
     * 4. 截止日期后支付：显示逾期天数，不再更新（promise = 2）
     */
    @Scheduled(cron = "0 0 1 * * ?") // 每天执行一次，持续扫描数据库
    public void updateHouseOrderComplianceStatus() {
        System.out.println("开始扫描房屋订单守约状态: " + LocalDateTime.now());

        Timestamp currentTime = Timestamp.valueOf(LocalDateTime.now());

        // 查询所有需要更新的订单（排除已经固定为逾期状态的订单）
        QueryWrapper<HouseOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("promise", 2); // 不等于2（已固定逾期状态）

        List<HouseOrder> orders = houseOrderMapper.selectList(queryWrapper);

        for (HouseOrder order : orders) {
            updateOrderComplianceStatus(order, currentTime);
        }

        System.out.println("房屋订单守约状态扫描完成: " + LocalDateTime.now());
    }

    /**
     * 应用启动时执行一次
     */
    @Scheduled(initialDelay = 5000, fixedDelay = Long.MAX_VALUE)
    public void initializeComplianceStatus() {
        System.out.println("应用启动时执行房屋订单守约状态初始化: " + LocalDateTime.now());
        updateHouseOrderComplianceStatus();
    }

    /**
     * 更新单个订单的守约状态
     */
    private void updateOrderComplianceStatus(HouseOrder order, Timestamp currentTime) {
        Byte newPromiseStatus = calculatePromiseStatus(order, currentTime);

        // 记录状态变化
        if (!newPromiseStatus.equals(order.getPromise())) {
            System.out.println("订单状态变化 - 订单ID: " + order.getId() +
                    ", promise: " + order.getPromise() + " -> " + newPromiseStatus);
        }

        // 检查是否逾期当天且未支付（promise状态为1且未支付）
        boolean shouldSendMessage = false;
        if ((order.getStatus() == null || order.getStatus() == 0) &&
                !currentTime.before(order.getDeadline()) &&
                newPromiseStatus == 1) {
            shouldSendMessage = true;
        }

        // 只有状态发生变化时才更新
        if (!newPromiseStatus.equals(order.getPromise())) {
            // 使用专门的安全更新方法，确保只更新promise字段，不影响deadline等其他字段
            int updateResult = houseOrderMapper.updatePromiseStatusOnly(order.getId(), newPromiseStatus);

            if (updateResult > 0) {
                System.out.println("更新订单ID: " + order.getId() + ", 守约状态: " + order.getPromise() + " -> " + newPromiseStatus);

                // 验证deadline字段没有被意外修改（额外的安全检查）
                HouseOrder updatedOrder = houseOrderMapper.selectById(order.getId());
                if (!order.getDeadline().equals(updatedOrder.getDeadline())) {
                    System.err.println("严重错误：定时任务更新过程中deadline字段被意外修改！");
                    System.err.println("订单ID: " + order.getId());
                    System.err.println("原deadline: " + order.getDeadline());
                    System.err.println("新deadline: " + updatedOrder.getDeadline());

                    // 立即恢复正确的deadline
                    UpdateWrapper<HouseOrder> restoreWrapper = new UpdateWrapper<>();
                    restoreWrapper.eq("id", order.getId())
                            .set("deadline", order.getDeadline());
                    houseOrderMapper.update(null, restoreWrapper);
                    System.out.println("已恢复正确的deadline: " + order.getDeadline());
                } else {
                    System.out.println("验证通过：deadline字段未被修改，值为: " + updatedOrder.getDeadline());
                }
            } else {
                System.err.println("警告：订单ID " + order.getId() + " 的promise状态更新失败");
            }
        }

        // 发送逾期当天的消息（在状态更新之后）
        if (shouldSendMessage) {
            try {
                sendHouseOrder.sendMessage(order.getId());
                System.out.println("租房订单逾期当天信用分消息发送成功 - 订单ID: " + order.getId());
            } catch (Exception e) {
                System.err.println("租房订单逾期当天信用分消息发送失败 - 订单ID: " + order.getId() + ", 错误: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /**
     * 计算守约状态
     * @param order 订单
     * @param currentTime 当前时间
     * @return 守约状态 (0: 守约/剩余天数, 1: 逾期天数, 2: 固定逾期状态)
     */
    private Byte calculatePromiseStatus(HouseOrder order, Timestamp currentTime) {
        // 如果已经是固定逾期状态，不再更新
        if (order.getPromise() != null && order.getPromise() == 2) {
            return (byte) 2;
        }

        // 已支付的情况
        if (order.getStatus() != null && order.getStatus() == 1) {
            // 如果在截止日期前支付，显示守约
            if (order.getPayDate() != null && order.getPayDate().before(order.getDeadline())) {
                return (byte) 0; // 守约
            }
            // 如果在截止日期当天或之后支付，固定为逾期状态
            else if (order.getPayDate() != null && !order.getPayDate().before(order.getDeadline())) {
                return (byte) 2; // 固定逾期状态，不再更新
            }
        }

        // 未支付的情况
        if (order.getStatus() == null || order.getStatus() == 0) {
            // 当前时间小于截止时间：剩余天数
            if (currentTime.before(order.getDeadline())) {
                return (byte) 0; // 剩余天数
            }
            // 当前时间大于等于截止时间：逾期天数
            else {
                return (byte) 1; // 逾期天数
            }
        }

        return order.getPromise(); // 保持原状态
    }
}